package util;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

/**
 * JDBC工具类2.0版本：可以为同一个线程的不同方法提供同一个连接对象
 *
 * 利用线程本地变量，存储连接对象，确保一个线程的多个方法可以获取同一个connection
 *  * 优势：事务操作的时候，service和dao属于同一个线程，不用再传递参数了，
 *  * 		都可以调用getConnection自动获取相同的连接对象。
 */
public class JdbcUtils {
    //数据库连接池对象
    private static DataSource dataSource = null;

    //线程本地变量：存储共享数据(连接对象)
    private static ThreadLocal<Connection> threadLocal = new ThreadLocal<>();

    static {    //只执行一次
        Properties properties = new Properties();
        InputStream is = JdbcUtils.class.getClassLoader()
                .getResourceAsStream("druid.properties");

        try {
            properties.load(is);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        try {
            dataSource = DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取连接
     */
    public static Connection getConnection() throws SQLException {
        //获取连接对象时：先看线程本地变量中有没有连接，有则直接返回，没有再通过连接池获取连接，并存入本地变量中。
        Connection connection = threadLocal.get(); //取
        if (connection == null) {
            connection = dataSource.getConnection();
            threadLocal.set(connection);    //存
        }
        return connection;
    }

    /**
     * 回收连接
     */
    public static void freeConnection() throws SQLException {
        Connection connection = threadLocal.get();
        if (connection != null) {
            threadLocal.remove();   //清空线程本地变量
            connection.setAutoCommit(true);
            connection.close();
        }
    }
}
